package com.logic.landseaserver.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.logic.landseaserver.persistence.read.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.logic.common.domain.Code;
import com.logic.common.exception.BusinessException;
import com.logic.common.security.SecurityUtils;
import com.logic.common.util.CurrentThread;
import com.logic.common.util.QueryUtil;
import com.logic.common.ws.dto.system.CodeDTO;
import com.logic.common.ws.dto.system.FileDTO;
import com.logic.landseaserver.common.LandeaConstants;
import com.logic.landseaserver.common.LandeaConstants.ReRentType;
import com.logic.landseaserver.common.LandseaErrorMessageEnum;
import com.logic.landseaserver.common.config.FileConfiguration;
import com.logic.landseaserver.common.enums.BTypeEnum;
import com.logic.landseaserver.common.enums.BillStatusEnum;
import com.logic.landseaserver.common.enums.BillTypeEnum;
import com.logic.landseaserver.common.enums.ContractStatusCodeEnum;
import com.logic.landseaserver.common.enums.DepositEnum;
import com.logic.landseaserver.common.enums.PaymentModelCodeEnum;
import com.logic.landseaserver.common.enums.RoomStatusCodeEnum;
import com.logic.landseaserver.common.exception.LandseaBusinessException;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.common.util.DateUtil;
import com.logic.landseaserver.common.util.FileTool;
import com.logic.landseaserver.common.util.PDF2Image;
import com.logic.landseaserver.domain.Bill;
import com.logic.landseaserver.domain.BillDetail;
import com.logic.landseaserver.domain.Contract;
import com.logic.landseaserver.domain.CustomerVersion;
import com.logic.landseaserver.domain.Deposit;
import com.logic.landseaserver.domain.Room;
import com.logic.landseaserver.domain.UserFile;
import com.logic.landseaserver.models.authcode.service.CouponUsedService;
import com.logic.landseaserver.models.independent.service.BillIndependentService;
import com.logic.landseaserver.models.prepayment.bean.AccountResp;
import com.logic.landseaserver.models.prepayment.bean.AddAccountObject;
import com.logic.landseaserver.models.prepayment.bean.CurrentAccount;
import com.logic.landseaserver.models.prepayment.service.PrepaymentService;
import com.logic.landseaserver.models.rerent.service.IReRentService;
import com.logic.landseaserver.persistence.write.BalanceSheetRecordWriteMapper;
import com.logic.landseaserver.persistence.write.BillDetailWriteMapper;
import com.logic.landseaserver.persistence.write.BillWriteMapper;
import com.logic.landseaserver.persistence.write.ContractWriteMapper;
import com.logic.landseaserver.persistence.write.DepositWriteMapper;
import com.logic.landseaserver.persistence.write.UserFileWriteMapper;
import com.logic.landseaserver.service.IBillService;
import com.logic.landseaserver.service.IContractService;
import com.logic.landseaserver.service.ICustomer;
import com.logic.landseaserver.service.IDdLockService;
import com.logic.landseaserver.service.IProjectAppartment;
import com.logic.landseaserver.ws.dto.BillDetailDTO;
import com.logic.landseaserver.ws.dto.ContractDTO;
import com.logic.landseaserver.ws.dto.ContractPdfDTO;
import com.logic.landseaserver.ws.dto.ProjectDetailDTO;
import com.logic.landseaserver.ws.dto.QueryCouponUesdDTO;
import com.logic.landseaserver.ws.dto.UserFileDTO;
import com.logic.landseaserver.ws.request.ContractNeedDelReq;
import com.logic.landseaserver.ws.request.RoomDetailReq;
import com.logic.system.domain.SystemFile;
import com.logic.system.persistence.write.FileWriteMapper;
import com.logic.system.service.ICodeService;
import com.logic.system.service.IConfigurationService;
import com.logic.system.service.IFileService;
import com.logic.system.ws.dto.CodeConverter;
import com.logic.system.ws.dto.FileConverter;

/**
 * @Author: Quintina.Yu
 * @Date: 2017/5/23
 * @Description: 用户
 */
@Service
public class ContractServiceImpl implements IContractService
{
    
    private static final Logger LOG = LoggerFactory.getLogger(ContractServiceImpl.class);
    
    @Autowired
    private ContractReadMapper contractReadMapper;
    
    @Autowired
    private UrgentReadMapper urgentReadMapper;
    
    @Autowired
    private IProjectAppartment projectAppartmentService;
    
    @Autowired
    private ContractWriteMapper contractWriteMapper;
    
    @Autowired
    private BillWriteMapper billWriteMapper;
    
    @Autowired
    private IFileService fileService;
    
    @Autowired
    private ICodeService codeService;
    
    @Autowired
    private FileWriteMapper fileWriteMapper;
    
    @Autowired
    private FileConfiguration fileConfiguration;
    
    @Autowired
    private IProjectAppartment roomService;
    
    @Autowired
    private IBillService billService;
    
    @Autowired
    private DepositReadMapper depositReadMapper;
    
    @Autowired
    private DepositWriteMapper depositWriteMapper;
    
    @Autowired
    private IConfigurationService configurationService;
    
    @Autowired
    private BillDetailReadMapper billDetailReadMapper;
    
    @Autowired
    private BillDetailWriteMapper billDetailWriteMapper;
    
    @Autowired
    private BalanceSheetRecordWriteMapper balanceSheetRecordWriteMapper;
    
    @Autowired
    private BillIndependentService billIndependentService;

    @Autowired
    private CouponUsedService couponUsedService;

    @Autowired
    private ICustomer customerService;

    @Autowired
    private UserFileWriteMapper userFileWriteMapper;

    @Autowired
    private UserFileReadMapper userFileReadMapper;

    @Autowired
    private IReRentService reRentService;
    
    @Autowired
    private PrepaymentService prepaymentService;
    
    @Autowired
    private IDdLockService ddLockService;

    @Autowired
    private CustomerCardReadMapper customerCardReadMapper;
    
    /**
     * 汉语中数字大写
     */
    private static final String[] CN_UPPER_NUMBER = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    
    /**
     * 汉语中货币单位大写，这样的设计类似于占位符
     */
    private static final String[] CN_UPPER_MONETRAY_UNIT =
        {"分", "角", "元", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾", "佰", "仟"};
    
    /**
     * 特殊字符：整
     */
    private static final String CN_FULL = "整";
    
    /**
     * 特殊字符：负
     */
    private static final String CN_NEGATIVE = "负";
    
    /**
     * 金额的精度，默认值为2
     */
    private static final int MONEY_PRECISION = 2;
    
    /**
     * 特殊字符：零元整
     */
    private static final String CN_ZEOR_FULL = "零元" + CN_FULL;
    
    private static final Logger log = LoggerFactory.getLogger(ContractOfflineServiceImpl.class);
    
    @Override
    public int insert(Object o)
        throws BusinessException
    {
        return 0;
    }
    
    @Override
    public Object get(Integer integer)
        throws BusinessException
    {
        ContractDTO contractDTO = contractReadMapper.queryContractDetail(integer);
        contractDTO.setUrgentDTO(urgentReadMapper.queryDetailByContractId(contractDTO.getId(), null));
        if (contractDTO.getPdfId() != null)
        {
            contractDTO.setPdf(FileConverter.fromFileToDTO((SystemFile)this.fileService.get(contractDTO.getPdfId())));
        }
        if (contractDTO.getPdfImg() != null)
        {
            contractDTO
                .setImage(FileConverter.fromFileToDTO((SystemFile)this.fileService.get(contractDTO.getPdfImg())));
        }
        //查询授权码使用信息
        HashMap map= new HashMap();
        map.put("mainId",contractDTO.getId());
        map.put("mainType",LandeaConstants.QueryUesdCodeType.CONTRACT);
        List<QueryCouponUesdDTO> codes= couponUsedService.querypPersonalCouponList(map);
        contractDTO.setAuthCodes(codes);
        //查询历史版本
        contractDTO.setHistoryFiles(queryHistoryVersions(integer));
        //查询银行卡信息
        contractDTO.setCustomerCardDTO(customerCardReadMapper.queryCardInfo(map));
        // 查询账户总金额
        AccountResp accountResp = prepaymentService.getAccountTotalMoney(contractDTO.getUserId(), contractDTO.getRoomId());
        if (null != accountResp)
        {
            contractDTO.setAccountId(accountResp.getId());
            contractDTO.setAccountTotalMoney(accountResp.getMoney());
        }
        
        return contractDTO;
    }
    
    @Override
    public void update(Object o)
        throws BusinessException
    {
        Contract contract = (Contract)o;
        contractWriteMapper.updateByPrimaryKeySelective(contract);
    }
    
    @Override
    public void delete(String s)
        throws BusinessException
    {
        
    }
    
    @Override
    public List<?> query(QueryUtil queryUtil)
    {
        return null;
    }
    
    @Override
    public List<ContractDTO> queryContractList(QueryUtil queryUtil)
        throws BusinessException
    {
        Integer systemId = SecurityUtils.getCurrentLogin().getUserId();
        if (systemId == null)
        {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.TOKEN_IS_NULL);
        }
        Map<String, Object> params = queryUtil.getParams();
        params.put("adminId", systemId);
        List<ContractDTO> list = contractReadMapper.queryContractPage(queryUtil);
        if (list.size() > 0)
        {
            for (ContractDTO contractDTO : list)
            {
                if (contractDTO.getPdfId() != null)
                {
                    contractDTO
                        .setPdf(FileConverter.fromFileToDTO((SystemFile)this.fileService.get(contractDTO.getPdfId())));
                }
                if (contractDTO.getPdfImg() != null)
                {
                    contractDTO.setImage(
                        FileConverter.fromFileToDTO((SystemFile)this.fileService.get(contractDTO.getPdfImg())));
                }
            }
        }
        return list;
    }
    
    @Override
    public Boolean validate(Object o)
        throws BusinessException
    {
        return null;
    }
    
    @Override
    public Boolean validateForInsert(Object o)
        throws BusinessException
    {
        return null;
    }
    
    @Override
    public Boolean validateForUpdate(Object o)
        throws BusinessException
    {
        return null;
    }
    
    @Override
    public Boolean validateForDelete(Object o)
        throws BusinessException
    {
        return null;
    }
    
    /**
     * 首付款后修改合同状态，增加合同编号，账单编号
     *
     * @param contractId
     * @param billId
     * @throws BusinessException
     */
    @Override
    public Bill updateAfterPay(Integer contractId, Integer billId, Date payTime)
        throws Exception
    {
        log.info("首付款回调，修改合同状态 增加合同编号，账单编号 " + contractId);
        Contract contract = contractReadMapper.selectByPrimaryKey(contractId);
        if (contract == null)
        {
            log.info("未查询到有效合同");
            throw new LandseaBusinessException(LandseaErrorMessageEnum.TOKEN_IS_NULL);
        }
        RoomDetailReq roomDetailDTO = projectAppartmentService.searchRoomInfo(contract.getRoomId());
        ProjectDetailDTO projectDetailDTO = roomDetailDTO.getProject();
        
        Bill bill = new Bill();
        if (roomDetailDTO != null && projectDetailDTO != null)
        {
            String contractSn = projectDetailDTO.getPrjCode()
                + new DecimalFormat("000000").format(contractReadMapper.getMaxContractCode());
            contract.setPayTime(new Date());
            contract.setStatus(ContractStatusCodeEnum.SIGN.getCode());
            contract.setContractNo(contractSn);
            contract.updateCommonInfo(-1);
            contractWriteMapper.updateByPrimaryKeySelective(contract);
            // 首付款 修改账单号 注意：只修改账单编号，禁止修改其他字段
            String billNo = contractSn + "01";
            bill.setId(billId);
            bill.setBillNo(billNo);
            bill.updateCommonInfo(-1);
            bill.setContractNo(contractSn);
            // 此处的创建时间一定不能改，bill表中的createedDtm计算滞纳金要用
            bill.setCreatedDtm(null);
            bill.setCreatedBy(null);
            billWriteMapper.updateByPrimaryKeySelective(bill);
            // 修改子项的detailNo
            List<BillDetailDTO> detailList = billDetailReadMapper.selectDetailListById(billId);
            Integer detailNum = 0;
            for (BillDetailDTO billDetail : detailList)
            {
                detailNum++;
                BillDetail detail = new BillDetail();
                detail.setId(billDetail.getId());
                detail.setDetailNo(billNo + String.format("%02d", detailNum));
                detail.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
                billDetailWriteMapper.updateByPrimaryKeySelective(detail);
                
                detail.setType(billDetail.getType());
                // 支付成功-更新独立账单
                billIndependentService.firUpdateBalanceSheet(billId, contractSn, detail, payTime);
            }
        }
        
        renameContractPdf(contract);
        
        // 首期支付成功后开通账户,但换房B合同账户不在此处开
        if (!(contract.getOriginalCId() != null && ReRentType.TURN.equals(contract.getRentType())))
        {
            // 首期支付成功后开通账户
            AddAccountObject object = new AddAccountObject();
            object.setRoomId(contract.getRoomId());
            object.setProjectId(contract.getProjectId());
            object.setUserId(contract.getUserId());
            object.setContractId(contract.getId());
            CurrentAccount currentAccount = prepaymentService.addAccount(object);
            
            CurrentThread.set("CURRENTACCOUNT", currentAccount);
        }
        
        // 如果是续租，则要延期门锁密码有效期
        if (contract.getOriginalCId() != null && ReRentType.RERENT.equals(contract.getRentType()))
        {
            LOG.info("续租B合同支付首期完成，开始门锁密码有效期延长.ContractId=" + contract.getId());
            // 如果有房租，则要重置密码有效期为房租截止日期,不需要发送短信
            ddLockService.resetPasswordEffectiveTime(contract.getRoomId(), bill.getContractId(), null);
        }
        
        return bill;
    }
    
    @Override
    public ContractPdfDTO getContractPdfDTO(Integer id)
        throws BusinessException
    {
        HashMap queryMap = new HashMap();
        queryMap.put("id",id);
        ContractPdfDTO dto = contractReadMapper.getContractPdfDTO(queryMap);
        if (null != dto)
        {
            if (null != dto.getProject().getCostType())
            {
                String costType = dto.getProject().getCostType();
                List<Code> codesType = codeService.getCodesByIds(costType);
                String costTypeZh = new String();
                if(codesType.size()>0){
                    for (Code code:codesType){
                        costTypeZh = costTypeZh + code.getCodeDescZh() + ",";
                    }
                    dto.setCostTypeZh(costTypeZh.substring(0, costTypeZh.length() - 1));
                }
            }
        }
        return dto;
    }
    
    @Override
    public Integer productContractPdf(int id,String oprType)
        throws Exception
    {
        HashMap queryMap = new HashMap();
        queryMap.put("id",id);
        if(oprType.equals(LandeaConstants.PdfOprType.CHANGE)){
            queryMap.put("versionNum",LandeaConstants.PdfOprType.CHANGE);
        }
        ContractPdfDTO dto = contractReadMapper.getContractPdfDTO(queryMap);
        // 计量类型
        String countCost = new String();
        // 非计量类型
        String useCost = new String();
        if (null != dto.getProject().getCostType())
        {
            String costType = dto.getProject().getCostType();
            String[] costcodes = costType.split(",");
            // String costTypeZh = new String();
            for (int i = 0; i < costcodes.length; i++)
            {
                // 实时的费用不用计算
                if (costcodes[i].indexOf("_") == 0)
                {
                    Code systemCode = codeService.getCode(costcodes[i]);
                    if (systemCode != null)
                    {
                        CodeDTO codeDto = CodeConverter.fromCodeToCodeDTO(systemCode);
                        String codeDescZh = codeDto.getCode_desc_zh();
                        if (codeDescZh.equals(BillTypeEnum.CTBI1.getName())
                            || codeDescZh.equals(BillTypeEnum.CTBI2.getName())
                            || codeDescZh.equals(BillTypeEnum.CTBI3.getName())
                            || codeDescZh.equals(BillTypeEnum.CTBI4.getName()))
                        {
                            countCost = countCost + codeDescZh + ",";
                        }
                        else
                        {
                            useCost = useCost + codeDescZh + ",";
                        }
                    }
                }
            }
            if (!StringUtils.isEmpty(countCost))
            {
                countCost = countCost.substring(0, countCost.length() - 1);
            }
            if (!StringUtils.isEmpty(useCost))
            {
                useCost = useCost.substring(0, useCost.length() - 1);
            }
            // dto.setCostTypeZh(costTypeZh.substring(0, costTypeZh.length() - 1));
        }
        Map<String, String> data = new HashMap<String, String>();
        data.put("contractId", String.valueOf(id));
        data.put("contractNo", dto.getContractNo());
        data.put("renterName", dto.getProject().getContractName());

        data.put("rentName", dto.getCertificatesName());
        data.put("renterTelephone", dto.getCellphone());
        data.put("idCodeType", dto.getCertificatesType());
        data.put("idCodeNum", dto.getCertificatesId());
        data.put("rentTel", dto.getCellphone());
        data.put("rentAdd", dto.getCertificatesAddress());
        data.put("rentDate", dto.getSignDate().substring(0, 10));
        if(oprType.equals(LandeaConstants.PdfOprType.CHANGE)){
            data.put("oy", dto.getLastMdfDate().substring(0, 4));
            data.put("om", dto.getLastMdfDate().substring(5, 7));
            data.put("od", dto.getLastMdfDate().substring(8, 10));
        }
        String city = dto.getAddress().getCity();
        String area = dto.getAddress().getCounty();
        try
        {
            data.put("city", city.substring(0, city.length() - 1));
            data.put("area", area.substring(0, area.length() - 1));
        }
        catch (Exception e)
        {
            throw new Exception("城市，地区没获取到");
        }
        data.put("detilAddress", dto.getAddress().getAddressLine1() + "," + dto.getRoom().getHouseNum() + "号房间");
        data.put("maxPeople", dto.getRoom().getMaxResident().toString());
        DecimalFormat df = new DecimalFormat("##0");
        String indate = dto.getInDate();
        SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat ymdFormatter = new SimpleDateFormat("yyyy-MM-dd");
        Date intime = ymdFormatter.parse(indate);
        Calendar calin = Calendar.getInstance();
        calin.setTime(intime);
        
        data.put("indateYear", calin.get(Calendar.YEAR) + "");
        data.put("indateMonth", (calin.get(Calendar.MONTH) + 1) + "");
        data.put("indateDay", calin.get(Calendar.DAY_OF_MONTH) + "");
        String outdate = dto.getOutDate();
        Date outtime = ymdFormatter.parse(outdate);
        Calendar calout = Calendar.getInstance();
        calout.setTime(outtime);
        data.put("outdateYear", calout.get(Calendar.YEAR) + "");
        data.put("outdateMonth", (calout.get(Calendar.MONTH) + 1) + "");
        data.put("outdateDay", calout.get(Calendar.DAY_OF_MONTH) + "");

      //  LeaseCodeEnum leaseCode = LeaseCodeEnum.getLeaseCodeEnum(dto.getLease());
        if(dto.getLeaseM() != null){
            int totalYear = (int)Math.floor(dto.getLeaseM()/12);
            data.put("totalYear",String.valueOf(totalYear));
            data.put("totalMonth", String.valueOf(dto.getLeaseM()%12));
            data.put("totalDay",dto.getLeaseD().toString());
           // data.put("totalDay",dto.getLeaseD()==null ? "" : dto.getLeaseD().toString());
           // data.put("totalMonth",leaseCode.getMonth() == 12 ?"0":String.valueOf(leaseCode.getMonth()));
           // data.put("totalDay","0");
        }

        data.put("giveYear", calin.get(Calendar.YEAR) + "");
        data.put("giveMonth", (calin.get(Calendar.MONTH) + 1) + "");
        data.put("giveDay", calin.get(Calendar.DAY_OF_MONTH) + "");
        data.put("rent", dto.getSalePrice()==null ? "" :  df.format(Double.valueOf(dto.getSalePrice()).doubleValue()));
        data.put("rentCh", number2CNMontrayUnit(new BigDecimal(dto.getSalePrice())));
        data.put("allpay", dto.getTotalMoney()==null ? "" :  df.format(Double.valueOf(dto.getTotalMoney()).doubleValue()));
        data.put("allpayCh", number2CNMontrayUnit(new BigDecimal(dto.getTotalMoney())));
        if(dto.getLeaseM()==0 && dto.getLeaseD()>0){
            data.put("rentType", "5");
        }else{
            Integer leaseM = dto.getLeaseM();
            if(dto.getLeaseD()>0){
                leaseM = leaseM+1;
            }
            Integer paymethod = PaymentModelCodeEnum.setPaymentModelCode(leaseM,dto.getPaymentMode());
            data.put("rentType", paymethod == null? "" :String.valueOf(paymethod));
        }

        Calendar calpay = Calendar.getInstance();
        if (null == dto.getSignDate())
        {
            throw new Exception("没有签约时间，不能生成合同！");
        }
        calpay.setTime(sdFormatter.parse(dto.getSignDate()));
        data.put("firstPayYear", calpay.get(Calendar.YEAR) + "");
        data.put("firstPayMonth", (calpay.get(Calendar.MONTH) + 1) + "");
        data.put("firstPayDay", calpay.get(Calendar.DAY_OF_MONTH) + "");
        Double dipositM = Double.valueOf(dto.getDeposit()).doubleValue();
        data.put("diposit",df.format(dipositM));
       // DecimalFormat df = new DecimalFormat("0.00");

        
        Double depositWater = dto.getWaterDeposit();
        // 水费押金
        data.put("depositWater", depositWater == null ? "" : df.format(depositWater));
        
        String alldiposit = df.format(dipositM+ depositWater);
        data.put("allDiposit", alldiposit);
        data.put("allDipositCH", number2CNMontrayUnit(new BigDecimal(alldiposit)));
        data.put("propertyFee", dto.getPropertyFee() == null ? "" : df.format(Double.valueOf(dto.getPropertyFee()).doubleValue()));
        data.put("propertyFeeCH", number2CNMontrayUnit(new BigDecimal(dto.getPropertyFee())));
        // data.put("otherFee", dto.getCostTypeZh());
        data.put("otherCountFee", countCost);
        data.put("otherUesdFee", useCost);
        data.put("gYear", calin.get(Calendar.YEAR) + "");
        data.put("gMonth", (calin.get(Calendar.MONTH) + 1) + "");
        data.put("gDay", calin.get(Calendar.DAY_OF_MONTH) + "");
        data.put("renter", dto.getProject().getContractName());
        data.put("renterTel", dto.getProject().getContractPhone());
        data.put("renterAdd", dto.getProject().getContractAddress());
        data.put("renterDate", dto.getSignDate().substring(0, 10));
        // data.put("rentN", dto.getCertificatesName());
        //Integer days = configurationService.getIntegerValue("SYS_TIM_FOR_LAT_FEE");
        Integer days = dto.getLatefeeDay();
        data.put("lateFeeDays", String.valueOf(days));
        // 收取滞纳金额百分比
        Double persentage = configurationService.getDoubleValue("SYS_PRO_OF_OVE_FIN");
        data.put("lateFeePercent", persentage * 100 + "%");
        data.put("lateFee", String.valueOf(days));

        data.put("contractStatus",dto.getStatus());
        if(dto.getCustomerCardDTO()!=null){
            data.put("cardAccount",dto.getCustomerCardDTO().getCardAccount()==null ? "":dto.getCustomerCardDTO().getCardAccount());
            data.put("cardUserName",dto.getCustomerCardDTO().getCardUserName()==null ? "":dto.getCustomerCardDTO().getCardUserName());
            data.put("cardCellPhone",dto.getCustomerCardDTO().getCellPhone()==null ? "":dto.getCustomerCardDTO().getCellPhone());
            data.put("bankName",dto.getCustomerCardDTO().getBankName()==null ? "":dto.getCustomerCardDTO().getBankName());
            data.put("bankBrname",dto.getCustomerCardDTO().getBankBrname()==null ? "":dto.getCustomerCardDTO().getBankBrname());
            data.put("cardNo",dto.getCustomerCardDTO().getCardNo()==null ? "":dto.getCustomerCardDTO().getCardNo());
        }
        Integer result = producePDF(data,oprType);
        return result;
    }
    
    @Override
    public void createPdf(Integer contractId)
        throws Exception
    {
        Integer pdfId = productContractPdf(contractId,LandeaConstants.PdfOprType.ADD_UPDATE);
        if (pdfId != null)
        {
            Contract contract = new Contract();
            contract.setId(contractId);
            contract.setPdfId(pdfId);
           // contract.updateCommonInfo(-1);
            //contractWriteMapper.updateByPrimaryKeySelective(contract);
            // 生成水印
            Integer imgId = createImg(pdfId);
           // contract.setId(contractId);
            contract.setPdfImg(imgId);
            contract.updateCommonInfo(-1);
            contractWriteMapper.updateByPrimaryKeySelective(contract);
        }
    }
    
    private Integer createImg(Integer pdfId)
        throws BusinessException, IOException
    {
        // 不存在 属于新增
        FileDTO fileDTO = FileConverter.fromFileToDTO((SystemFile)this.fileService.get(pdfId));
        if (fileDTO != null)
        {
            String fileName = fileDTO.getName().replace(".pdf", ".jpg");
            String imageLocalFullPath =
                fileConfiguration.getLocal() + "/" + fileConfiguration.getContract_path() + "/" + fileName;
            PDF2Image.createImg(fileDTO.getLocalFullPath(), imageLocalFullPath);
            // 保存水印图片到数据库
            SystemFile systemFile = new SystemFile();
            systemFile.setPath(fileConfiguration.getContract_path());
            systemFile.setFileType("jpg");
            systemFile.setName(fileName);
            systemFile.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
            fileWriteMapper.insertSelective(systemFile);
            return systemFile.getId();
        }
        return null;
    }
    
    public Integer producePDF(Map<String, String> data,String oprType)
        throws Exception
    {
        OutputStream fos = null;
        ByteArrayOutputStream bos = null;
        Integer fileId = null;
        try
        {
            PdfReader reader = null;
            String contractStatus = (String) data.get("contractStatus");
            if(oprType.equals(LandeaConstants.PdfOprType.CHANGE) && !contractStatus.equals(ContractStatusCodeEnum.NEW.getCode())){
                 reader = new PdfReader(ContractServiceImpl.class.getClassLoader().getResource("landseaPDFModelV.pdf"));
            }else {
                 reader = new PdfReader(ContractServiceImpl.class.getClassLoader().getResource("landseaPDFModel.pdf"));
            }
            bos = new ByteArrayOutputStream();
            /* 将要生成的目标PDF文件名称 */
            PdfStamper ps = new PdfStamper(reader, bos);
            // PdfContentByte under = ps.getUnderContent(7);
            /* 使用中文字体 */
            BaseFont bf =
                BaseFont.createFont(ContractServiceImpl.class.getClassLoader().getResource("STSONG.TTF").toString(),
                    BaseFont.IDENTITY_H,
                    BaseFont.NOT_EMBEDDED);
            // Font font = FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD);
            ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
            fontList.add(bf);
            /* 取出报表模板中的所有字段 */
            AcroFields fields = ps.getAcroFields();
            fields.setSubstitutionFonts(fontList);
            fillData(fields, data);
            
            /*
             * //盖章图片 List<AcroFields.FieldPosition> list = fields.getFieldPositions("sealimage"); Rectangle signRect =
             * list.get(0).position; Image image = Image.getInstance("D:/pdf/zhang.gif");
             *
             * float x = signRect.getLeft(); float y = signRect.getBottom(); image.setAbsolutePosition(x, y);
             * image.scaleAbsolute(100, 100); under.addImage(image);
             */
            
            /* 给pdf加密 */
            // ps.setEncryption("Hello".getBytes(),"world".getBytes(),PdfWriter.ALLOW_SCREENREADERS,PdfWriter.STANDARD_ENCRYPTION_128);
            ps.setFormFlattening(true);
            ps.close();
            String filepath = fileConfiguration.getLocal() + "/" + fileConfiguration.getContract_path();
            File file = new File(filepath);
            // 如果文件夹不存在则创建
            if (!file.exists() && !file.isDirectory())
            {
                file.mkdir();
            }
            Date nowTime = new Date(System.currentTimeMillis());
            SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
            String time = sdFormatter.format(nowTime);
            String filename = filepath + "/" + "C" + data.get("contractId") + "_" + time + ".pdf";
            fos = new FileOutputStream(filename);
            fos.write(bos.toByteArray());
            
            // 将url插入数据库
            SystemFile systemFile = new SystemFile();
            int size = bos.size() / 1024;
            systemFile.setFileSize(size);
            systemFile.setPath(fileConfiguration.getContract_path());
            systemFile.setFileType("pdf");
            systemFile.setName("C" + data.get("contractId") + "_" + time + ".pdf");
            systemFile.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
            fileWriteMapper.insertSelective(systemFile);
            fileId = systemFile.getId();
            
        }
        catch (Exception e)
        {
            LOG.error("producePDF error", e);
            return null;
        }
        finally
        {
            fos.flush();
            fos.close();
            bos.close();
        }
        return fileId;
    }
    
    /*
     * public static ContractPdfDTO getContract(Integer id){ ContractPdfDTO dto = contractService.getContractPdfDTO(id);
     * return dto; }
     */
    
    public static void fillData(AcroFields fields, Map<String, String> data)
        throws IOException, DocumentException
    {
        for (String key : data.keySet())
        {
            String value = data.get(key);
            fields.setField(key, value); // 为字段赋值,注意字段名称是区分大小写的
        }
    }
    
    /**
     * 把输入的金额转换为汉语中人民币的大写
     *
     * @param numberOfMoney 输入的金额
     * @return 对应的汉语大写
     */
    public static String number2CNMontrayUnit(BigDecimal numberOfMoney)
    {
        StringBuffer sb = new StringBuffer();
        // -1, 0, or 1 as the value of this BigDecimal is negative, zero, or
        // positive.
        int signum = numberOfMoney.signum();
        // 零元整的情况
        if (signum == 0)
        {
            return CN_ZEOR_FULL;
        }
        // 这里会进行金额的四舍五入
        long number = numberOfMoney.movePointRight(MONEY_PRECISION).setScale(0, 4).abs().longValue();
        // 得到小数点后两位值
        long scale = number % 100;
        int numUnit = 0;
        int numIndex = 0;
        boolean getZero = false;
        // 判断最后两位数，一共有四中情况：00 = 0, 01 = 1, 10, 11
        if (!(scale > 0))
        {
            numIndex = 2;
            number = number / 100;
            getZero = true;
        }
        if ((scale > 0) && (!(scale % 10 > 0)))
        {
            numIndex = 1;
            number = number / 10;
            getZero = true;
        }
        int zeroSize = 0;
        while (true)
        {
            if (number <= 0)
            {
                break;
            }
            // 每次获取到最后一个数
            numUnit = (int)(number % 10);
            if (numUnit > 0)
            {
                if ((numIndex == 9) && (zeroSize >= 3))
                {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[6]);
                }
                if ((numIndex == 13) && (zeroSize >= 3))
                {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[10]);
                }
                sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                sb.insert(0, CN_UPPER_NUMBER[numUnit]);
                getZero = false;
                zeroSize = 0;
            }
            else
            {
                ++zeroSize;
                if (!(getZero))
                {
                    sb.insert(0, CN_UPPER_NUMBER[numUnit]);
                }
                if (numIndex == 2)
                {
                    if (number > 0)
                    {
                        sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                    }
                }
                else if (((numIndex - 2) % 4 == 0) && (number % 1000 > 0))
                {
                    sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
                }
                getZero = true;
            }
            // 让number每次都去掉最后一个数
            number = number / 10;
            ++numIndex;
        }
        // 如果signum == -1，则说明输入的数字为负数，就在最前面追加特殊字符：负
        if (signum == -1)
        {
            sb.insert(0, CN_NEGATIVE);
        }
        // 输入的数字小数点后两位为"00"的情况，则要在最后追加特殊字符：整
        if (!(scale > 0))
        {
            sb.append(CN_FULL);
        }
        return sb.toString();
    }
    
    @Override
    public List getMyContracts(QueryUtil queryUtil)
        throws LandseaBusinessException
    {
        Integer userId = SecurityUtils.getCurrentLogin().getUserId();
        if (userId == null || userId == -1)
        {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.TOKEN_IS_NULL);
        }
        Map<String, Object> params = queryUtil.getParams();
        if (params == null)
        {
            params = new HashMap<>();
        }
        params.put("userId", userId);
        
        return contractReadMapper.queryContractPage(queryUtil);
    }
    
    @Override
    public ContractDTO getMyContractsById(Integer id)
        throws BusinessException
    {
        Integer userId = SecurityUtils.getCurrentLogin().getUserId();
        if (userId == null || userId == -1)
        {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.TOKEN_IS_NULL);
        }
        ContractDTO contractDTO = contractReadMapper.queryContractDetail(id);
        
        if (contractDTO == null)
        {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.CONTRACT_GETDETAIL_IS_NULL);
        }
        // 查询登陆者是否是合同的签约人
        if (contractDTO.getUserId().compareTo(userId) != 0)
        {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.CONTRACT_GETDETAIL_IS_NULL);
        }
        if (contractDTO.getPdfImg() != null)
        {
            
            FileDTO image = FileConverter.fromFileToDTO((SystemFile)this.fileService.get(contractDTO.getPdfImg()));
            contractDTO.setImage(image);
        }
        contractDTO.setUrgentDTO(urgentReadMapper.queryDetailByContractId(contractDTO.getId(), null));
        return contractDTO;
    }
    
    @Override
    public void deleteNoPayContracts(List<ContractNeedDelReq> list)
    {
        if (list != null && list.size() > 0)
        {
            contractWriteMapper.deleteNoPayContracts(list);
        }
    }
    
    @Override
    public List<ContractNeedDelReq> needDeletedContract(Integer minuteMis)
    {
        if (minuteMis != null)
        {
            return contractReadMapper.needDeletedContract(minuteMis);
        }
        return null;
    }
    
    /**
     * 事务已添加
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void deleteContractList(Integer minuteMis)
    {
        List<ContractNeedDelReq> contractList = contractReadMapper.needDeletedContract(minuteMis);
        if (contractList != null && contractList.size() > 0)
        {
            // 恢复房源
            roomService.resetNoPayRoom(contractList);
            // 删除账单
            billService.deleteNoPayBill(contractList);
            // 删除合同
            deleteNoPayContracts(contractList);
            // 删除独立账单
            deleteBalanceByContract(contractList);
            //删除授权码使用记录
            for(ContractNeedDelReq ctc: contractList){
                couponUsedService.deleteCouponUesd(ctc.getId(),LandeaConstants.QueryUesdCodeType.CONTRACT);
            }
        }
    }
    
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void deleteById(Integer id)
        throws BusinessException,LandseaException
    {
        ContractDTO contractDTO = contractReadMapper.queryContractDetail(id);
        if (contractDTO == null)
        {
            throw new LandseaBusinessException(LandseaErrorMessageEnum.DELETE_CONTRACT_CONTRACT_IS_NULL);
        }
        Deposit dsInfo = null;
        //续租合同删除
        if(contractDTO.getOriginalCId()!=null && contractDTO.getRentType().equals(LandeaConstants.ReRentType.RERENT)){
            reRentService.cancelReRent(contractDTO.getOriginalCId());
            return;
        }
        // 如果有定金，则判断有没有其他支付记录
        if (contractDTO.getDepositId() != null)
        {
            dsInfo = depositReadMapper.selectByPrimaryKey(contractDTO.getDepositId());
            if (dsInfo != null && contractDTO.getAmountReceived() != null)
            {
                if (dsInfo.getDepositAmount().compareTo(contractDTO.getAmountReceived()) != 0)
                {
                    throw new LandseaBusinessException(LandseaErrorMessageEnum.DELETE_CONTRACT_HAS_PAY);
                }
            }
        }
        else
        {
           // if(contractDTO.getOriginalCId()==null){
                if (contractDTO.getAmountReceived() != null && contractDTO.getAmountReceived() > 0)
                {
                    throw new LandseaBusinessException(LandseaErrorMessageEnum.DELETE_CONTRACT_HAS_PAY);
                }
           // }else{
                //获取首付款
               /* Bill parBill = billService.queryFirstBill(contractDTO.getId());
                HashMap queryMap = new HashMap();
                queryMap.put("billId",parBill.getId());
                List<BillPaymentDTO> billPayments = billPaymentReadMapper.selectListByBillId(queryMap);
                for(BillPaymentDTO dto:billPayments){
                    if (!dto.getPayType().equals(PaymentConstant.PayChannel.HOURSEDEPOSIT) &&
                            !dto.getPayType().equals(PaymentConstant.PayChannel.WATER_DEPOSIT)) {
                        throw LandseaException.createException(LandseaErrorMessageEnum.UPDATE_ROOM_ID_IS_NULL);
                    }
                }
            }*/
        }

        List<ContractNeedDelReq> contractList = new ArrayList<ContractNeedDelReq>();
        ContractNeedDelReq req = new ContractNeedDelReq();
        req.setRoomId(contractDTO.getRoomId());
        req.setId(contractDTO.getId());
        contractList.add(req);
        // 恢复房源
        roomService.resetNoPayRoom(contractList);
        // 删除账单
        billService.deleteNoPayBill(contractList);
        // 删除合同
        deleteNoPayContracts(contractList);
        // 根据合同删除独立账单
        deleteBalanceByContract(contractList);
        //删除授权码使用记录
        couponUsedService.deleteCouponUesd(contractDTO.getId(), LandeaConstants.QueryUesdCodeType.CONTRACT);
        
        // 恢复定金 1：状态修改 2：房间状态修改
        if (dsInfo != null)
        {
            String availableDate = DateUtil.getInstence().convertDate(dsInfo.getAvailableDate()) + " 23:59:59";
            if (DateUtil.getInstence().convertDate(availableDate).getTime() < (new Date().getTime()))
            {
                // 将定金改为已过期
                dsInfo.setStatus(DepositEnum._DS4.getCode());
                dsInfo.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
                depositWriteMapper.updateByPrimaryKeySelective(dsInfo);
                // 判断此房间是否再有效合同内
                Integer counts = contractReadMapper.queryApartContractCounts(dsInfo.getRoomId());
                if (counts == 0)
                {
                    Room room = new Room();
                    room.setId(dsInfo.getRoomId());
                    room.setAppendStatus(RoomStatusCodeEnum.LRB1.getCode());
                    roomService.updateAppendStatus(room);
                }
            }
            else
            {
                // 将定金改为未使用
                dsInfo.setStatus(DepositEnum._DS2.getCode());
                dsInfo.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
                depositWriteMapper.updateByPrimaryKeySelective(dsInfo);
                // 判断此房间是否再有效合同内
                Integer counts = contractReadMapper.queryApartContractCounts(dsInfo.getRoomId());
                if (counts == 0)
                {
                    Room room = new Room();
                    room.setId(dsInfo.getRoomId());
                    room.setAppendStatus(RoomStatusCodeEnum.LRB2.getCode());
                    roomService.updateAppendStatus(room);
                }
            }
            
            // 删除负数的定金平帐用的独立账单
            Map<String,Object> deleteMap = new HashMap<String,Object>();
            deleteMap.put("depositId", dsInfo.getId());
            deleteMap.put("billType", BTypeEnum._BT4.getCode());
            deleteMap.put("expenditureCode", BillTypeEnum.CTBI18.getCode());
            deleteMap.put("billstatus", BillStatusEnum.BIST2.getCode());
            balanceSheetRecordWriteMapper.removeNegativeDeposit(deleteMap);
        }
    }

    @Override
    public void renameContractPdf(Contract contract)
        throws BusinessException
    {
        if(StringUtils.isEmpty(contract.getContractNo())){
            contract = contractReadMapper.selectByPrimaryKey(contract.getId());
        }
        Integer userId = SecurityUtils.getCurrentLogin().getUserId();
        String fileName = contract.getContractNo()+"01";

        HashMap queryMap = new HashMap();
        queryMap.put("path",fileConfiguration.getContract_path());
        queryMap.put("fileType","pdf");
        queryMap.put("name",contract.getContractNo());
        List<SystemFile> systemFiles = fileService.getFilesByMap(queryMap);
        if(systemFiles.size()>0){
            fileName =contract.getContractNo()+String.format("%02d", systemFiles.size()+1);
        }
        if (contract.getPdfId() != null)
        {
            SystemFile localPdfFile = (SystemFile)fileService.get(contract.getPdfId() + "");
            String pdfName = fileName + ".pdf";
            if (localPdfFile != null)
            {
                FileTool.reName(localPdfFile.getLocalFullPath(), pdfName);
            }
            SystemFile pdfFile = new SystemFile();
            pdfFile.setId(contract.getPdfId());
            pdfFile.setName(pdfName);
            pdfFile.updateCommonInfo(userId);
            fileWriteMapper.updateByPrimaryKeySelective(pdfFile);
        }
        if (contract.getPdfImg() != null)
        {
            SystemFile localPdfImgFile = (SystemFile)fileService.get(contract.getPdfImg() + "");
            String imgName = fileName + ".jpg";
            FileTool.reName(localPdfImgFile.getLocalFullPath(), imgName);
            SystemFile imgFile = new SystemFile();
            imgFile.setId(contract.getPdfImg());
            imgFile.setName(imgName);
            imgFile.updateCommonInfo(userId);
            fileWriteMapper.updateByPrimaryKeySelective(imgFile);
        }
    }
    
    @Override
    public void testCreatePDFImg()
        throws IOException, BusinessException
    {
        List<Contract> contractList = contractReadMapper.queryPDFImgIsNull();
        for (Contract contract : contractList)
        {
            Integer imgId = createImg(contract.getPdfId());
            contract.setId(contract.getId());
            contract.setPdfImg(imgId);
            contract.updateCommonInfo(-1);
            contractWriteMapper.updateByPrimaryKeySelective(contract);
        }
    }
    
    /**
     * 
     * [简要描述]：根据合同删除独立账单表</br>
     * [详细描述]：</br>
     * [作者]：Aaron(2017-09-22)</br>
     *
     * @param contractList
     *
     */
    @Override
    public void deleteBalanceByContract(List<ContractNeedDelReq> contractList)
    {
        if (CollectionUtils.isEmpty(contractList))
        {
            return;
        }
        
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("lastModifiedBy", SecurityUtils.getCurrentLogin().getUserId());
        map.put("lastModifiedDtm", new Date());
        
        for (ContractNeedDelReq req : contractList)
        {
            map.put("contractId", req.getId());
            balanceSheetRecordWriteMapper.deleteByContractId(map);
        }
    }


    @Override
    public void updateVersion(Integer contractId) throws Exception {
        //check是否符合变更的条件
        if(contractId!=null){
            ContractDTO contract = contractReadMapper.queryContractDetail(contractId);
            if(contract==null){
                throw LandseaException.createException(LandseaErrorMessageEnum.CUSTOMER_VERSION_NOT_LASTEST);
            }
            String contractUser = contract.getCertificatesName().concat(contract.getCellphone()).concat(contract.getCertificatesType()).concat(contract.getCertificatesId());
            CustomerVersion cv = customerService.getNewVersion(contract.getUserId());
            String latestUser = cv.getName().concat(cv.getPhone()).concat(cv.getCertificatesType()).concat(cv.getCertificatesNo());
            if(contractUser.equals(latestUser)){
                throw LandseaException.createException(LandseaErrorMessageEnum.CUSTOMER_VERSION_NOT_LASTEST);
            }
            UserFile userFile = new UserFile();
            userFile.setMainId(contract.getId());
            userFile.setMainType(LandeaConstants.QueryUesdCodeType.CONTRACT);
            userFile.setPdfId(contract.getPdfId());
            userFile.setPdfImgId(contract.getPdfImg());
            userFile.setUserId(contract.getUserId());
            userFile.setOldVersion(contract.getUserVersion());
            userFile.setUserVersion(cv.getVersionNumber());
            userFile.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
            //Step 1 重新生成PDF
            Integer pdfId = productContractPdf(contractId,LandeaConstants.PdfOprType.CHANGE);
            if (pdfId != null) {
                // 生成水印
                Integer imgId = createImg(pdfId);
                Contract contractMd = new Contract();
                contractMd.setId(contractId);
                contractMd.setPdfId(pdfId);
                contractMd.setPdfImg(imgId);
                contractMd.setUserVersion(cv.getVersionNumber());
                contractMd.setIsChapter(false);
                contractMd.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());
                contractWriteMapper.updateByPrimaryKeySelective(contractMd);
            }
            //Step 2 预定合同变更新增记录
            if(!contract.getStatus().equals(ContractStatusCodeEnum.NEW.getCode())){
                userFileWriteMapper.insertSelective(userFile);
            }
        }
    }

    @Override
    public List<UserFileDTO> queryHistoryVersions(Integer contractId) throws BusinessException {
        HashMap map = new HashMap();
        map.put("mainId",contractId);
        map.put("mainType",LandeaConstants.QueryUesdCodeType.CONTRACT);
        List<UserFileDTO> userFileDTOs = userFileReadMapper.queryHistoryFile(map);
        if(userFileDTOs!=null){
            for(UserFileDTO dto:userFileDTOs){
                if (dto.getPdfId() != null)
                {
                    dto.setPdfPath(FileConverter.fromFileToDTO((SystemFile)this.fileService.get(dto.getPdfId())).getFullPath());
                }
                if (dto.getPdfImgId() != null)
                {
                    dto.setImgPath(FileConverter.fromFileToDTO((SystemFile)this.fileService.get(dto.getPdfImgId())).getFullPath());
                }
            }
        }
        return userFileDTOs;
    }

    @Override
    public Integer getChangeVersionCount(Integer projectId) {
        return contractReadMapper.queryChangeVersionCount(SecurityUtils.getCurrentLogin().getUserId(),projectId);
    }

    @Override
    public void updateContractEnd(String inDate) {
        HashMap queryMap = new HashMap();
        queryMap.put("inDate",inDate);
        queryMap.put("rentType",LandeaConstants.ReRentType.RERENT);
        List<Contract> contractList = contractReadMapper.queryReRentContract(queryMap);
        if(contractList.size()>0){
            for(Contract contract:contractList){
                Contract updateContract = new Contract();
                updateContract.setId(contract.getOriginalCId());
                updateContract.setStatus(ContractStatusCodeEnum.END.getCode());
                updateContract.updateCommonInfo(contract.getLastModifiedBy());
                contractWriteMapper.updateByPrimaryKeySelective(updateContract);
                log.info("updateContractEnd for rerent contract id is :" +contract.getOriginalCId());
            }
        }
    }

    @Override
    public Integer getChangeRentCount(Integer projectId) {
        return contractReadMapper.queryChangeRentCount(SecurityUtils.getCurrentLogin().getUserId(),projectId);
    }
}
